<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HLS视频播放器测试</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            color: #fff;
            min-height: 100vh;
            padding: 20px;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 15px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
        }
        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
        }
        .subtitle {
            font-size: 1.2rem;
            opacity: 0.9;
        }
        .player-container {
            display: flex;
            flex-direction: column;
            gap: 30px;
        }
        .player-section {
            background: rgba(0, 0, 0, 0.4);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
        }
        .section-title {
            font-size: 1.5rem;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 2px solid rgba(255, 255, 255, 0.2);
        }
        .video-container {
            width: 100%;
            background: #000;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
        }
        video {
            width: 100%;
            height: auto;
            max-height: 70vh;
        }
        .controls {
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            margin-top: 20px;
        }
        .input-group {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-width: 200px;
        }
        label {
            margin-bottom: 8px;
            font-weight: 600;
        }
        input, select, button {
            padding: 12px 15px;
            border: none;
            border-radius: 8px;
            font-size: 1rem;
            background: rgba(255, 255, 255, 0.1);
            color: white;
            backdrop-filter: blur(10px);
        }
        input:focus, select:focus {
            outline: 2px solid #fdbb2d;
        }
        button {
            background: linear-gradient(to right, #fdbb2d, #b21f1f);
            color: white;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }
        button:hover {
            transform: translateY(-3px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        button:active {
            transform: translateY(0);
        }
        .status {
            margin-top: 20px;
            padding: 15px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 8px;
            font-family: monospace;
            white-space: pre-wrap;
            max-height: 200px;
            overflow-y: auto;
        }
        .resolution-info {
            display: flex;
            gap: 10px;
            margin-top: 15px;
            flex-wrap: wrap;
        }
        .resolution-badge {
            background: rgba(253, 187, 45, 0.2);
            padding: 5px 10px;
            border-radius: 20px;
            font-size: 0.9rem;
        }
        .info-section {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
        }
        .info-card {
            background: rgba(0, 0, 0, 0.3);
            padding: 20px;
            border-radius: 10px;
        }
        .info-card h3 {
            margin-bottom: 10px;
            color: #fdbb2d;
        }
        .info-card p {
            line-height: 1.6;
        }
        .footer {
            text-align: center;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid rgba(255, 255, 255, 0.2);
            font-size: 0.9rem;
            opacity: 0.8;
        }
        @media (max-width: 768px) {
            .controls {
                flex-direction: column;
            }
            .input-group {
                min-width: 100%;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <header>
        <h1>HLS视频播放器测试</h1>
        <p class="subtitle">用于测试文件管理系统的HLS视频播放接口</p>
    </header>

    <div class="player-container">
        <div class="player-section">
            <h2 class="section-title">视频播放器</h2>
            <div class="video-container">
                <video id="videoPlayer" controls></video>
            </div>

            <div class="controls">
                <div class="input-group">
                    <label for="fileId">文件ID:</label>
                    <input type="text" id="fileId" value="23" placeholder="输入文件ID">
                </div>

                <div class="input-group">
                    <label for="baseUrl">API基础URL:</label>
                    <!-- http://127.0.0.1:8050/api -->
                    <input type="text" id="baseUrl" value="https://inewu.api.moyoz.online/api" placeholder="输入API基础URL">
                </div>

                <div class="input-group">
                    <label for="resolution">分辨率 (可选):</label>
                    <select id="resolution">
                        <option value="">自动选择</option>
                        <option value="480p">480p</option>
                        <option value="720p">720p</option>
                        <option value="1080p">1080p</option>
                    </select>
                </div>

                <button id="loadVideoBtn">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <polygon points="5 3 19 12 5 21 5 3"></polygon>
                    </svg>
                    加载视频
                </button>

                <button id="clearBtn">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <circle cx="12" cy="12" r="10"></circle>
                        <line x1="15" y1="9" x2="9" y2="15"></line>
                        <line x1="9" y1="9" x2="15" y2="15"></line>
                    </svg>
                    清除状态
                </button>
            </div>

            <div class="status" id="status">
                等待加载视频...
            </div>
        </div>

        <div class="player-section">
            <h2 class="section-title">播放信息</h2>
            <div class="info-section">
                <div class="info-card">
                    <h3>接口说明</h3>
                    <p>主播放列表: <code>/manage/file/preview/hls/public/{fileId}/master.m3u8</code></p>
                    <p>分片文件: <code>/manage/file/preview/hls/public/{fileId}/{resolution}/{segmentName}</code></p>
                </div>

                <div class="info-card">
                    <h3>使用说明</h3>
                    <p>1. 输入文件ID和API基础URL</p>
                    <p>2. 选择分辨率或使用自动选择</p>
                    <p>3. 点击"加载视频"开始播放</p>
                    <p>4. 使用播放器控件控制播放</p>
                </div>

                <div class="info-card">
                    <h3>技术说明</h3>
                    <p>使用hls.js库实现HLS视频播放</p>
                    <p>支持多分辨率自适应</p>
                    <p>无需认证即可播放公开视频</p>
                </div>
            </div>
        </div>
    </div>

    <div class="footer">
        <p>HLS视频播放器测试页面 &copy; 2025</p>
    </div>
</div>

<!-- 引入hls.js库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/hls.js/1.4.10/hls.min.js"></script>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        const videoPlayer = document.getElementById('videoPlayer');
        const fileIdInput = document.getElementById('fileId');
        const baseUrlInput = document.getElementById('baseUrl');
        const resolutionSelect = document.getElementById('resolution');
        const loadVideoBtn = document.getElementById('loadVideoBtn');
        const clearBtn = document.getElementById('clearBtn');
        const statusDiv = document.getElementById('status');

        let hls = null;

        // 更新状态信息
        function updateStatus(message) {
            statusDiv.textContent = message;
            console.log(message);
        }

        // 加载视频
        function loadVideo() {
            const fileId = fileIdInput.value.trim();
            const baseUrl = baseUrlInput.value.trim();
            const resolution = resolutionSelect.value;
            if (!fileId) {
                updateStatus('错误: 请输入文件ID');
                return;
            }

            if (!baseUrl) {
                updateStatus('错误: 请输入API基础URL');
                return;
            }

            // 停止当前播放
            if (hls) {
                hls.destroy();
                hls = null;
            }

            // 构建视频URL
            let videoUrl;
            if (resolution) {
                // 直接使用指定分辨率的播放列表
                videoUrl = `${baseUrl}/manage/file/preview/hls/public/${fileId}/${resolution}/index.m3u8`;
            } else {
                // 使用主播放列表（自动选择分辨率）
                videoUrl = `${baseUrl}/manage/file/preview/hls/public/${fileId}/master.m3u8`;
            }

            updateStatus(`正在加载视频...\nURL: ${videoUrl}`);

            if (Hls.isSupported()) {
                hls = new Hls({
                    debug: false,
                    enableWorker: false,
                    lowLatencyMode: true,
                    backBufferLength: 90
                });

                hls.loadSource(videoUrl);
                hls.attachMedia(videoPlayer);

                hls.on(Hls.Events.MANIFEST_PARSED, function() {
                    updateStatus(`视频加载成功!\n可用分辨率: ${hls.levels.map(level => level.height + 'p').join(', ')}`);
                    videoPlayer.play().catch(e => {
                        updateStatus(`自动播放被阻止: ${e.message}\n请手动点击播放按钮`);
                    });
                });

                hls.on(Hls.Events.ERROR, function(event, data) {
                    if (data.fatal) {
                        let errorMsg = `HLS错误: ${data.type} - ${data.details}`;
                        updateStatus(errorMsg);

                        switch(data.details) {
                            case Hls.ErrorDetails.MANIFEST_LOAD_ERROR:
                                updateStatus('错误: 无法加载播放列表，请检查文件ID和URL');
                                break;
                            case Hls.ErrorDetails.MANIFEST_LOAD_TIMEOUT:
                                updateStatus('错误: 播放列表加载超时');
                                break;
                            case Hls.ErrorDetails.MANIFEST_PARSING_ERROR:
                                updateStatus('错误: 播放列表解析错误');
                                break;
                            case Hls.ErrorDetails.LEVEL_LOAD_ERROR:
                                updateStatus('错误: 分辨率加载错误');
                                break;
                            case Hls.ErrorDetails.LEVEL_LOAD_TIMEOUT:
                                updateStatus('错误: 分辨率加载超时');
                                break;
                            case Hls.ErrorDetails.FRAG_LOAD_ERROR:
                                updateStatus('错误: 分片加载错误');
                                break;
                            default:
                                updateStatus(`未知错误: ${data.details}`);
                                break;
                        }
                    }
                });

                hls.on(Hls.Events.LEVEL_SWITCHED, function(event, data) {
                    const level = hls.levels[data.level];
                    console.log(level);
                    updateStatus(`切换到分辨率: ${level.height}p, 码率: ${Math.round(level.bitrate/1000)} kbps`);
                });

            } else if (videoPlayer.canPlayType('application/vnd.apple.mpegurl')) {
                // 原生HLS支持 (Safari)
                videoPlayer.src = videoUrl;
                
                videoPlayer.addEventListener('loadedmetadata', function() {
                    updateStatus('视频加载成功 (原生HLS支持)');
                    videoPlayer.play();
                });
            } else {
                updateStatus('错误: 您的浏览器不支持HLS播放');
            }
        }

        // 清除状态
        function clearStatus() {
            if (hls) {
                hls.destroy();
                hls = null;
            }
            videoPlayer.src = '';
            updateStatus('状态已清除，等待加载视频...');
        }

        // 事件监听
        loadVideoBtn.addEventListener('click', loadVideo);
        clearBtn.addEventListener('click', clearStatus);

        // 初始状态
        updateStatus('准备就绪，请输入文件ID和API基础URL，然后点击"加载视频"');
    });
</script>
</body>
</html>